import React from 'react';
import { Button, Input, Table, message, Rate, Popconfirm, Popover } from 'antd';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import _ from 'lodash';
import './index.less';
import { loadAssets, ignoreOneday, cancelIgnoreOneday, batchUpdateAssets } from '@api/asset';
import EditOrgModal from '../../../../asset-manage/components/edit-org-modal';
import Tag from '@components/tag';

class SiteList extends React.Component {
  static propTypes = {
    active: PropTypes.bool,
    desc: PropTypes.string,
    type: PropTypes.string,
    onedayId: PropTypes.string,
    baseQuery: PropTypes.object,
    reloadOneday: PropTypes.func,
    exportAssetForm: PropTypes.func,
    socketIO: PropTypes.object,
    socketIOInstance: PropTypes.object
  };
  constructor(props) {
    super(props);
    this.state = {
      page: 1,
      pageSize: 10,
      count: 0,
      selectedRows: [],
      sites: [],
      search: '',
      loading: false,
      editAttrVisable: false,
      orgValue: '',
      // eslint-disable-next-line
      staffValue: undefined
    };
  }
  componentDidMount() {
    this.loadSites();
  }

  componentDidUpdate(prevProps) {
    if (prevProps.active !== this.props.active && this.props.active) {
      this.loadSites();
    }
  }

  loadSites = () => {
    const { page, pageSize, search } = this.state;
    this.setState({ loading: true });
    loadAssets({ query: { search, ...this.props.baseQuery }, pagaition: { page, pageSize } })
      .then(res => {
        const { list = [], count = 0 } = _.get(res, 'data.data', {});
        this.setState({ sites: list, count });
      })
      .catch(err => {
        window.console.log(err);
        message.error('加载资产列表失败');
      })
      .finally(() => {
        this.setState({ loading: false });
      });
  };
  cancelIgnoreOneday = siteId => {
    cancelIgnoreOneday(siteId, this.props.onedayId)
      .then(() => {
        message.success('已取消忽略该资产');
        this.loadSites();
        this.props.reloadOneday();
      })
      .catch(() => {
        message.error('取消忽略该资产失败');
      });
  };
  ignoreOneday = siteId => {
    ignoreOneday(siteId, this.props.onedayId)
      .then(() => {
        message.success('已忽略该资产');
        this.loadSites();
        this.props.reloadOneday();
      })
      .catch(() => {
        message.error('忽略该资产失败');
      });
  };

  exportAssetForm = () => {
    const siteIds = _.map(this.state.selectedRows, '_id');
    if (!siteIds.length && !this.state.count) {
      return message.info('未选择资产或当前资产数为空');
    }
    const query = siteIds.length
      ? { siteIds }
      : { search: this.state.search, ...this.props.baseQuery };
    this.props.exportAssetForm({
      query,
      onedayId: this.props.onedayId,
      description: this.props.desc
    });
  };

  submitEditAssetAttr = () => {
    const { orgValue, staffValue } = this.state;
    const siteIds = _.map(this.state.selectedRows, '_id');
    if (!siteIds.length && !this.state.count) {
      return message.info('未选择资产或当前资产数为空');
    }
    if (!(orgValue || staffValue)) {
      return message.info('未选择资产所属组织或人员');
    }
    const query = siteIds.length
      ? { siteIds }
      : { search: this.state.search, ...this.props.baseQuery };
    batchUpdateAssets({
      query,
      set: _.pickBy({ organization: orgValue, staffOid: staffValue }, Boolean)
    }).then(res => {
      if (res.data.result) {
        message.success('编辑资产成功!');
        this.loadSites();
        // eslint-disable-next-line
        this.setState({ editAttrVisable: false, orgValue: '', staffValue: undefined });
      }
    });
  };

  notifyAdmin = () => {
    // 通知管理员
    const { socketIO, baseQuery, onedayId, type } = this.props;
    const siteIds = _.map(this.state.selectedRows, '_id');
    const query = siteIds.length
      ? { siteIds, ...baseQuery }
      : { search: this.state.search, ...this.props.baseQuery };
    socketIO.send({
      query,
      onedayId,
      type,
      // eslint-disable-next-line
      handler_name: 'notice_handler',
      method: 'send_oneday_warn_email'
    });
    message.success('已添加至邮件发送队列!');
  };

  render() {
    const {
      page,
      pageSize,
      count,
      sites,
      loading,
      selectedRows,
      editAttrVisable,
      orgValue,
      staffValue
    } = this.state;

    return (
      <div className="oneday-site-list">
        <div className="oneday-site-list-header">
          <div className="left">
            {this.props.type !== 'ignore' && (
              <Popconfirm
                title="确认通知管理员吗?"
                onConfirm={() => this.notifyAdmin()}
                okText="确认"
                cancelText="取消"
              >
                <Button>通知管理员</Button>
              </Popconfirm>
            )}
            <Button onClick={() => this.setState({ editAttrVisable: true })}>编辑资产属性</Button>
            <Button type="primary" onClick={this.exportAssetForm}>
              下载
            </Button>
          </div>
          <div className="right">
            <Input.Search
              onSearch={v => this.setState({ search: v }, this.loadSites)}
              placeholder="输入ip地址、url、资产名称、管理员搜索"
            />
          </div>
        </div>
        <div className="msg">
          共有&quot;{count}&quot;个 {this.props.desc}
        </div>
        <Table
          loading={loading}
          columns={[
            {
              title: 'IP地址',
              dataIndex: 'ip',
              render: (ip, row) => {
                return <span>{row.ip || row.ipv6}</span>;
              }
            },
            {
              title: 'url',
              dataIndex: 'url'
            },
            {
              title: '资产名称',
              dataIndex: 'name',
              render: (name, row) => {
                return <span>{name || [].concat(row.titles).join(',') || ''}</span>;
              }
            },
            {
              title: '资产分类',
              dataIndex: 'assetCategories',
              className: 'asset-categories',
              render: assetCategories => {
                return _.map(assetCategories, category =>
                  [_.get(category, 'parent.name'), _.get(category, 'name')]
                    .filter(Boolean)
                    .join('/')
                )
                  .filter(Boolean)
                  .map(ac => (
                    <span className="asset-cateogry" key={ac}>
                      {ac}
                    </span>
                  ));
              }
            },
            {
              title: '所属部门',
              dataIndex: 'organization',
              render: organization => {
                if (_.get(organization, 'length')) {
                  let name = organization.join('/');
                  return name ? <span className="organization">{name}</span> : null;
                }
              }
            },
            {
              title: '管理员',
              dataIndex: 'staff.nickname'
            },
            {
              title: '标签',
              dataIndex: 'tags',
              render: tags => {
                return _.map(tags, ({ name, color }) => (
                  <Tag key={name} value={name} color={color} />
                ));
              }
            },
            {
              title: '资产权重',
              dataIndex: 'weight',
              render: weight => <Rate value={weight} />
            },
            {
              title: '端口信息',
              dataIndex: 'portInfos',
              render: portInfos => {
                const portDescs = _.map(portInfos, portInfo => {
                  return [
                    portInfo.port,
                    portInfo.service,
                    _.map(portInfo.components, 'fullName').join(',')
                  ].join('/');
                }).map(i => ({ c: i, t: i }));
                if (portDescs.length > 4) {
                  portDescs[3] = {
                    c: '...',
                    t: _.map(portDescs.slice(3), ({ t }, i) => <div key={i}>{t}</div>)
                  };
                  portDescs.length = 4;
                }
                return (
                  <div className="port-infos">
                    {portDescs.map(({ c, t }, i) => (
                      <Popover key={i} title={null} content={t}>
                        <span className="port-info-item">{c}</span>
                      </Popover>
                    ))}
                  </div>
                );
              }
            },
            {
              title: '操作',
              key: 'opt',
              render: record => {
                const { _id: siteId, url, ip, ipv6, name } = record || {};
                const search = [
                  url ? `exact:url="${url}"` : '',
                  ip ? `exact:ip="${ip}"` : '',
                  ipv6 ? `exact:ip="${ipv6}"` : '',
                  name ? `exact:name="${name}"` : ''
                ]
                  .filter(Boolean)
                  .join(' && ');
                return (
                  <div className="opts">
                    {this.props.type === 'ignore' ? (
                      <Popconfirm
                        title="是否要取消忽略该资产"
                        onConfirm={() => this.cancelIgnoreOneday(siteId)}
                      >
                        <a className="cancel-ignore">取消忽略</a>
                      </Popconfirm>
                    ) : (
                      <Popconfirm
                        title="是否要忽略该资产"
                        onConfirm={() => this.ignoreOneday(siteId)}
                      >
                        <a className="ignore">忽略</a>
                      </Popconfirm>
                    )}
                    <a
                      className="jump-to-detail"
                      target="_blank"
                      rel="noopener noreferrer"
                      href={`/asset-manage?${encodeURIComponent(search)}`}
                    >
                      详情
                    </a>
                  </div>
                );
              }
            }
          ]}
          rowKey="_id"
          rowSelection={{
            onChange: (keys = [], rows = []) => {
              const { selectedRows } = this.state;
              const lastSelectedRows = selectedRows.filter(row => keys.includes(row._id));
              const uniqSelectedRows = _.uniqBy(rows.concat(lastSelectedRows), '_id');
              this.setState({
                selectedRows: uniqSelectedRows
              });
            },
            selectedRowKeys: _.map(selectedRows, '_id')
          }}
          onChange={({ current: page, pageSize }) =>
            this.setState({ page, pageSize }, this.loadSites)
          }
          dataSource={sites}
          pagination={{
            current: page,
            pageSize: pageSize,
            total: count,
            showQuickJumper: true,
            showSizeChanger: true
          }}
        />
        <EditOrgModal
          visible={editAttrVisable}
          title="编辑"
          withBelongTo={true}
          onClose={() => this.setState({ editAttrVisable: false })}
          changeOrgValue={orgValue => this.setState({ orgValue })}
          changeStaffValue={staffValue => this.setState({ staffValue })}
          orgValue={orgValue}
          staffValue={staffValue}
          onAttrSubmit={() => this.submitEditAssetAttr()}
        />
      </div>
    );
  }
}

const mapStateToProps = state => {
  return {
    socketIO: _.get(state, 'socketIO.socketIO', null),
    socketIOInstance: _.get(state, 'socketIO.socketIO.socketIO', null)
  };
};

export default connect(
  mapStateToProps,
  null
)(SiteList);
